package com.hex.ds.hdtp.core.app.common.util;

import cn.hutool.core.util.StrUtil;
import com.hex.ds.hdtp.core.app.common.entity.BasicContrastInfo;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.*;

@Slf4j
public class DatabaseStreamContrastUtil {


    /**
     * @Method getCommonStrDataType
     * @Param
     * @Return java.util.List<java.lang.String>
     * @Description 获取通用字符数据类型
     * @Author gj.xu
     * @Date 2024/2/21 16:30
     * @Version V2.0
     */
    private static List<String> getCommonStrDataType() {
        return Arrays.asList("CHAR", "VARCHAR", "VARCHAR2", "NVARCHAR", "CLOB", "NCHAR", "NVARCHAR2", "NCLOB", "RAW", "BLOB", "BFILE");
    }

    /**
     * @Method getCommonNumDataType
     * @Param
     * @Return java.util.List<java.lang.String>
     * @Description 获取通用数值数据类型
     * @Author gj.xu
     * @Date 2024/2/21 16:30
     * @Version V2.0
     */
    private static List<String> getCommonNumDataType() {
        return Arrays.asList("NUMBER", "BINARY_FLOAT", "BINARY_DOUBLE", "FLOAT", "DECIMAL", "INTEGER", "LONG", "SMALLINT", "BIGINT", "INT", "DOUBLE", "NUMERIC", "INT1", "INT2", "INT4", "INT8");
    }

    /**
     * @Method dataToQueueConvertType <br>
     * @Param rs
     * @Param isCharNullToEmpty
     * @Param isNumberNullToZero <br>
     * @Return java.util.Queue <br>
     * @Description 查询源表数据，并做类型转换<br>
     * @Author jian.qiao<br>
     * @Date 2023/9/27 17:15 <br>
     * @Version V1.0<br>
     */
    public static Queue dataToQueueConvertType(ResultSet rs, String isCharNullToEmpty, String isNumberNullToZero, BasicContrastInfo contrastInfo, Map<String, String> targetMap) throws SQLException {
        List<String> fieldList = new ArrayList<>(targetMap.keySet());
        Queue queue = new LinkedList<>();
        ResultSetMetaData rsm = rs.getMetaData();
        int numberFlag = 0;
        while (rs.next()) {
            Map<Integer, Map<String, Object>> result = new LinkedHashMap<>();
            Map<String, Object> record = new LinkedHashMap<>();
            for (int i = 1; i <= rsm.getColumnCount(); i++) {
                if (StrUtil.equalsIgnoreCase("Y", isCharNullToEmpty)
                        && (getCommonStrDataType().contains(rsm.getColumnTypeName(i).toUpperCase()))) {
                    //字符类型转换为空
                    String obj = rs.getString(i);
                    String columnName = rsm.getColumnName(i).toUpperCase();
                    record.put(columnName.toLowerCase(), (obj == null) ? "" : obj.trim());
                } else if (StrUtil.equalsIgnoreCase("Y", isNumberNullToZero)
                        && (getCommonNumDataType().contains(rsm.getColumnTypeName(i).toUpperCase()))) {
                    //数值类型转换为0
                    handleNumType(rs, targetMap, i, rsm, fieldList, record);
                } else {
                    handleDefaultType(rs, targetMap, rsm, i, fieldList, record);
                }
            }
            result.put(numberFlag, record);
            queue.add(result);
            numberFlag++;
        }
        return queue;
    }

    /**
     * @Method handleDefaultType
     * @Param rs
     * @Param targetMap
     * @Param rsm
     * @Param i
     * @Param fieldList
     * @Param record
     * @Return void
     * @Description 默认类型转换
     * @Author gj.xu
     * @Date 2024/2/22 17:48
     * @Version V2.0
     */
    private static void handleDefaultType(ResultSet rs, Map<String, String> targetMap, ResultSetMetaData rsm, int i, List<String> fieldList, Map<String, Object> colRecord) throws SQLException {
        String columnName = rsm.getColumnName(i).toUpperCase();
        if (fieldList.contains(columnName) && rs.getString(i) != null) {
            BigDecimal bigDecimal = new BigDecimal(rs.getString(i));
            bigDecimal = bigDecimal.setScale(Integer.valueOf(targetMap.get(columnName)), RoundingMode.HALF_UP);
            colRecord.put(columnName.toLowerCase(), bigDecimal.toString().trim());
        } else {
            Object data = rs.getString(i);
            colRecord.put(columnName.toLowerCase(), data == null ? data : data.toString().trim());
        }
    }

    /**
     * @Method handleNumType
     * @Param rs
     * @Param targetMap
     * @Param i
     * @Param rsm
     * @Param fieldList
     * @Param record
     * @Return void
     * @Description 数值类型转换为0
     * @Author gj.xu
     * @Date 2024/2/22 17:41
     * @Version V2.0
     */
    private static void handleNumType(ResultSet rs, Map<String, String> targetMap, int i, ResultSetMetaData rsm, List<String> fieldList, Map<String, Object> colRecord) throws SQLException {
        String obj = rs.getString(i);
        String columnName = rsm.getColumnName(i).toUpperCase();
        if (fieldList.contains(columnName) && obj != null) {
            BigDecimal bigDecimal = new BigDecimal(obj);
            bigDecimal = bigDecimal.setScale(Integer.valueOf(targetMap.get(columnName)), RoundingMode.HALF_UP);
            colRecord.put(columnName.toLowerCase(), bigDecimal.toString().trim());
        } else {
            colRecord.put(columnName.toLowerCase(), (obj == null) ? "0" : obj.trim());
        }
    }

    public static Queue dataToQueue(ResultSet rs) throws SQLException {
        Queue queue = new LinkedList<>();
        ResultSetMetaData rsm = rs.getMetaData();
        int count = rsm.getColumnCount();
        Map<String, Object> record = new HashMap<>();
        Map<Integer, Map<String, Object>> result = new HashMap<>();
        if (count > 0) {
            int numberFlag = 0;
            while (rs.next()) {
                record = new HashMap<String, Object>();
                for (int j = 0; j < count; j++) {
                    Object obj = rs.getObject(j + 1);
                    String columnName = rsm.getColumnName(j + 1).toUpperCase();
                    record.put(columnName.toLowerCase(), (obj == null) ? "" : obj);
                }
                result.put(numberFlag, record);
                queue.add(result);
                numberFlag++;
            }
        }
        return queue;
    }

    public static Map<Integer, Map<String, Object>> dataToMap(ResultSet rs, String isCharNullToEmpty, String isNumberNullToZero, BasicContrastInfo contrastInfo, Map<String, String> targetMap) throws SQLException {
        Map<Integer, Map<String, Object>> rows = new LinkedHashMap<>();
        List<String> fieldList = new ArrayList<>(targetMap.keySet());
        ResultSetMetaData rsm = rs.getMetaData();
        int count = rsm.getColumnCount();
        if (count <= 0) {
            return rows;
        }
        int numberFlag = 0;
        while (rs.next()) {
            Map<String, Object> record = new LinkedHashMap<>();
            for (int j = 0; j < count; j++) {
                String columnTypeName = rsm.getColumnTypeName(j + 1);
                if (StrUtil.equalsIgnoreCase("Y", isCharNullToEmpty)
                        && (getCommonStrDataType().contains(rsm.getColumnTypeName(j + 1).toUpperCase()))) {
                    //字符类型转换为空
                    String obj = rs.getString(j + 1);
                    String columnName = rsm.getColumnName(j + 1).toUpperCase();
                    record.put(columnName.toLowerCase(), (obj == null) ? "" : obj.trim());
                } else if (StrUtil.equalsIgnoreCase("Y", isNumberNullToZero)
                        && (getCommonNumDataType().contains(rsm.getColumnTypeName(j + 1).toUpperCase()))) {
                    //数值类型转换为0
                    handleNumType(rs, targetMap, j+1, rsm, fieldList, record);
                } else {
                    handleDefaultType(rs, targetMap, rsm, j + 1, fieldList, record);
                }
            }
            rows.put(numberFlag, record);
            numberFlag++;
        }
        return rows;
    }

}
